#pragma once
#include <iostream>
#include <string>
#include<string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

#include"pipe.hpp"

const std::string gpathName = "/home/wk/linux"; // 路径名可随意指定
const int gpro_id = 101;                        // 项目id随便指定
const int gSize = 4096;
const mode_t gmode = 0600;


class ShareMemary
{
    void CreateHelper(int flag)
    {
        // 1.获取一个key
        _key = ftok(gpathName.c_str(), gpro_id);
        // 2. 创建共享内存
        _shmid = shmget(_key, gSize, flag);
        if (_shmid == -1)
            std::cout << "创建shm失败" << std::endl;
        else
            std::cout << "创建成功:shmid: " << _shmid << std::endl;
    }

public:
    ShareMemary()
        : _shmid(-1), _key(0), _addr(nullptr)
    {
    }
    ~ShareMemary()
    {
    }

    void CreateSHM()
    {
        if (_shmid == -1)
            CreateHelper(IPC_CREAT | IPC_EXCL | gmode);
    }

    void GetSHM()
    {
        CreateHelper(IPC_CREAT);
    }

    void Attach()
    {
        _addr = shmat(_shmid, nullptr, 0);
        if ((long long)_addr == -1)
            std::cout << "挂接失败" << std::endl;
        else
            printf("挂接成功：%p\n", _addr);
    }

    void DeAttach()
    {
        if (_addr != nullptr)
            shmdt(_addr);
    }

    void DeleteSHM()
    {
        int del = shmctl(_shmid, IPC_RMID, nullptr);
        if (del == -1)
            std::cout << "删除失败" << std::endl;
        else
            std::cout << "删除成功" << std::endl;
    }

    void* GetAddr()
    {
        return _addr;
    }

private:
    int _shmid;
    key_t _key;
    void *_addr;
};

ShareMemary shm;